package core.xmpp;
import core.GlobalConfig;
import core.Main;
import java.util.Date;
import java.util.Iterator;
import org.jivesoftware.smack.*;
import org.jivesoftware.smack.packet.*;
import tools.Logger;


/**
 * Core XMPP connection
 * @author dcrm
 */
public class CoreXMPP implements Runnable {
    public static XMPPConnection connection;

    public String WELCOME_MSG="";

    private Thread thread;
    private final String THREAD_NAME ="XMPP_CORE";

    public String i_Jid;
    public String i_Jid_Master;
    public String i_Jid_Server;
    public int i_Jid_Port;
    public String i_Jid_Login;
    public String i_Jid_Place;
    private String i_Jid_Pwd;
    private CoreXMPP CORE;


    /**
     * Init XMPP connection
     * @param Jid - Jabber ID
     * @param Jid_Master - Jabber master ID
     * @param Jid_Server - Jabber server
     * @param Jid_Port - Jabber server port
     * @param Jid_Login - Jabber login
     * @param Jid_Pwd - Jabber password
     * @param Jid_Place- Jabber place
     */
    public CoreXMPP(String Jid, String Jid_Master, String Jid_Server,int Jid_Port, String Jid_Login, String Jid_Pwd, String Jid_Place) {
        this.i_Jid=Jid;
        this.i_Jid_Master=Jid_Master;
        this.i_Jid_Server=Jid_Server;
        this.i_Jid_Port=Jid_Port;
        this.i_Jid_Login=Jid_Login;
        this.i_Jid_Pwd=Jid_Pwd;
        this.i_Jid_Place=Jid_Place;
        
        thread = new Thread(this);
        thread.setName(THREAD_NAME+"["+Jid_Login+"]");
        thread.start();
    }

    public void run() {
    try {
            ConnectionConfiguration config = new ConnectionConfiguration(this.i_Jid_Server, this.i_Jid_Port);
            config.setSASLAuthenticationEnabled(true);
            SASLAuthentication.supportSASLMechanism("PLAIN", 0);
            this.CORE=this;
            connection = new XMPPConnection(config);
            connection.connect();
            connection.login(this.i_Jid_Login, this.i_Jid_Pwd, this.i_Jid_Place);
            this.WELCOME_MSG="Инфхель XMPP Онлайн: "+this.i_Jid_Server+":"+this.i_Jid_Port+"; JID: "+this.i_Jid_Login+"; Старт: "+new Date().toLocaleString();

            Presence p = new Presence(Presence.Type.available);
            p.setStatus("Let's Talk!");
            connection.sendPacket(p);
            sendIMADM(WELCOME_MSG);

            connection.getChatManager().addChatListener(new ChatManagerListener() {

                public void chatCreated(Chat chat, boolean createdLocally) {
                    chat.addMessageListener(new MessageListener() {

                        public void processMessage(Chat chat, Message message) {
                            checkRoster(message);
                            if (GlobalConfig.F_LOG_MSG) {Main.pr("XMPP["+message.getFrom()+"->"+message.getBody()+"]\n",true);}
                            new IncomeMsg(chat, message, connection, CORE);
                            if (GlobalConfig.F_BACK_MSG) {sendIMBack(message);}
                        }
                    });
                }
            });

            while (connection.isConnected()) Thread.sleep(100);
        } catch (Exception ex) {Logger.writelnErr(ex.getMessage());}
    }

    public void sendIM(String message, Chat c) {
        try {
            Message botRespose = new Message();
            botRespose.setBody(message);
            c.sendMessage(botRespose);
        } catch (Exception ex) {Logger.writelnErr(ex.getMessage());}
    }

   public void sendIM(String message, String to) {
        try {
            Message msg = new Message(to, Message.Type.chat);
            msg.setBody(message);
            connection.sendPacket(msg);
        } catch (Exception ex) {Logger.writelnErr(ex.getMessage());}
    }

   public void sendIMBack(Message message) {
        try {
            Message msg = new Message(i_Jid_Master, Message.Type.chat);
            String txt = "["+message.getFrom()+"->"+message.getBody()+"]";
            msg.setBody(txt);
            connection.sendPacket(msg);
        } catch (Exception ex) {Logger.writelnErr(ex.getMessage());}
    }

   public void sendIMADM(String message) {
        try {
            Message msg = new Message(i_Jid_Master, Message.Type.chat);
            msg.setBody(message);
            connection.sendPacket(msg);
        }
        catch (Exception ex) {Logger.writelnErr(ex.getMessage());}
    }

    public void disconnect(boolean exit) {
        sendIMADM("By-by!");
        connection.disconnect();
        try { Thread.sleep(1000);
        this.run();
        } catch (Exception ex) { Logger.writelnErr(ex.getMessage());}
        if (exit) Main.exit();
    }

    public void addToRoster(String targetUser, String targetName) {
	Roster roster = connection.getRoster();
	try {
		roster.createEntry(targetUser, targetName, null);
	} catch (Exception ex){Logger.writelnErr(ex.getMessage());}
    }
    
    public void checkRoster(Message message) {
        Roster roster = connection.getRoster();
        Iterator<RosterEntry> iter = roster.getEntries().iterator();
        boolean check=false;
        while(iter.hasNext()) {
            RosterEntry rosterEntry =(RosterEntry)iter.next();
            String q0=rosterEntry.getUser().toString();
            String q1=message.getFrom().toString();
            
            if ( q0.equalsIgnoreCase(q1) ) {
                check=true;
            }
        } if (!check) {addToRoster(message.getFrom(), message.getFrom());}
    }

    public String getState() { return WELCOME_MSG; }
}
